#include "imgifsc.h"
#include "pgma_io.h"

/*****************************************************
* Função para inverter imagem armazenada em uma
* estrutura Img. Inversão realiza a operação:
* I(u,v) = a_maxGray - I(u,v), onde
* I(u,v) representa a intensidade de um pixel na
* posição (u,v) e a_maxGray é o maior nível de
* intensidade armazenado no campo maxgray da struct.
*
* Entrada: ponteiro para struct Img
* Saída: nenhum retorno. Alteração na mesma imagem
* de entrada
*
* Desenvolvedor: Fernando S. Pacheco
* IFSC 2014
******************************************************/
void invertImg(struct Img *img) {
    int i,j;
    int *dataptr=img->data;
    for (i=0; i<img->height; i++) {
        for (j=0; j<img->width; j++) {
            *(dataptr) = img->maxgray - *(dataptr);
            dataptr++;
        }
    }
}

/*****************************************************
* Função para testar invertImg
*
* Entrada: nenhuma
* Saída: (int) 1 se sucesso; 0 se falha
*
* Desenvolvedor: Fernando S. Pacheco
* IFSC 2014
******************************************************/
int TESTinvertImg(void) {
    struct Img imgt;
    //criar estrutura para guardar imagem teste 3x3
    imgt.width = 3;
    imgt.height = 3;
    imgt.maxgray = 255;
    int nbytes = imgt.width * imgt.height * sizeof(int);
    //alocar espaço para dados
    imgt.data = (int *) malloc(nbytes);
    //criar uma imagem para teste, inserindo dados pixel a pixel
    int *dataptr=imgt.data;
    *(dataptr)=0; dataptr++;
    *(dataptr)=10; dataptr++;
    *(dataptr)=20; dataptr++;
    *(dataptr)=128; dataptr++;
    *(dataptr)=128; dataptr++;
    *(dataptr)=128; dataptr++;
    *(dataptr)=200; dataptr++;
    *(dataptr)=255; dataptr++;
    *(dataptr)=255;

    //gravar entrada para posterior análise
    pgma_write ("TESTEinvertImg.input.ascii.pgm", imgt.width, imgt.height, imgt.data);

    //chamar função a testar
    invertImg(&imgt);

    //gravar saída para posterior análise
    pgma_write ("TESTEinvertImg.output.ascii.pgm", imgt.width, imgt.height, imgt.data);

    //verificar se está ok
    // primeiro, informações complementares (width, height, maxgray)
    if (imgt.width!=3) goto FAIL;
    if (imgt.height!=3) goto FAIL;
    if (imgt.maxgray!=255) goto FAIL;
    // agora, pixel a pixel
    dataptr=imgt.data;
    if (*(dataptr) != 255) goto FAIL;
    dataptr++;
    if (*(dataptr) != 245) goto FAIL;
    dataptr++;
    if (*(dataptr) != 235) goto FAIL;
    dataptr++;
    if (*(dataptr) != 127) goto FAIL;
    dataptr++;
    if (*(dataptr) != 127) goto FAIL;
    dataptr++;
    if (*(dataptr) != 127) goto FAIL;
    dataptr++;
    if (*(dataptr) != 55) goto FAIL;
    dataptr++;
    if (*(dataptr) != 0) goto FAIL;
    dataptr++;
    if (*(dataptr) != 0) goto FAIL;

    free(imgt.data); //lembrar de sempre desalocar
    return 1;

    FAIL:
      free(imgt.data); //lembrar de sempre desalocar
      return 0;
}
